/**
 * @brief    瞬态分析测试
 *
 * @version  0.1
 * @author   wjw
 * @date     2025.03.11
 *         _
 *     ___| |__   ___ _ __   __ _  ___  _ __   __ _
 *    / __| '_ \ / _ \ '_ \ / _` |/ _ \| '_ \ / _` |
 *    \__ \ | | |  __/ | | | (_| | (_) | | | | (_| |
 *    |___/_| |_|\___|_| |_|\__, |\___/|_| |_|\__, |
 *                          |___/             |___/
 * @copyright (c) 2025 by 神工仿真, All Rights Reserved.
 */
#pragma once
#include "gtest/gtest.h"

#include "SGFem/Task/Kernel/MModel.h"
#include "SGFem/Task/Solver/TransientModalSolver.h"

using SG::DataStructure::Common::Status;
using SG::DataStructure::FEM::Project;
using namespace SG::DBManager;

extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;

struct TransientModalAnalysisTestData
{
    std::string         m_inputFile;    ///< 输入文件名称
    std::vector<double> m_modalTarget;  ///< Nastran响应结果
    SG::Algebra::Real_t m_error;        ///< 误差上限
};

class TransientModalTest : public ::testing::TestWithParam<TransientModalAnalysisTestData>
{
  protected:
    void SetUp () override
    {
        modelPath = getTestDataPath ("SGFem/ModalAnalysis/");
    }

    void TearDown () override
    {
        DB_SERVICEFACTORY->ClearDatabase ();
    }
    std::string modelPath;  ///< 输入模型文件路径
};

TEST_P (TransientModalTest, ComputeResponseAsExpect)
{
    // Input
    auto para = GetParam ();
    Project project;
    project.m_modelFilePath = modelPath;
    project.m_modelFileName = para.m_inputFile;
    auto posi               = para.m_inputFile.find ('.');
    project.m_jobName       = para.m_inputFile.substr (0, posi);

    DB_SERVICEFACTORY->ClearDatabase ();
    SG::Import::SGImporter importer (DB_SERVICEFACTORY);
    auto                   status = importer.Import (project.m_modelFilePath + project.m_modelFileName);
    ASSERT_EQ (status, Status::STATUS_Success);

    auto       subcaseIds = DB_SERVICEFACTORY->get<ISubcaseService> ()->GetAllSubcaseID (); // 获取模型中所有的subCase
    const auto subcaseId  = subcaseIds[0];

    // Test data
    TransientModalSolver solver;
    solver.Solve (DB_SERVICEFACTORY, project, subcaseIds[0]);

    Kernel::MModel      ModelTest (SG::DataStructure::FEM::SOLType::SOL_SEMTRAN, DB_SERVICEFACTORY);
    auto                            paraS = DB_SERVICEFACTORY->get<ISubcaseService> ()->FindSubCase (subcaseId);
    SG::DataStructure::FEM::Subcase subcase (paraS);

    const auto                                   tStepId = subcase.GetTSTEPId ();
    std::vector<SG::DataStructure::Common::Real> t;
    std::vector<SG::DataStructure::Common::Real> tOut;
    ModelTest.QueryTimeStep (tStepId, t, tOut);

    SG::Algebra::Vec_t  V;
    std::vector<SG::DataStructure::Common::Real> modalTest;
    for (auto &&ti : t)
    {
        ModelTest.GetDisplacement (subcaseId, ti, _OUT V);
        modalTest.push_back (V (269));
    }

    // Target data
    const auto modalTarget = para.m_modalTarget;

    // Check 计算相对误差
    SG::DataStructure::Common::Real numerator_norm   = 0.0;
    SG::DataStructure::Common::Real denominator_norm = 0.0;
    SG::DataStructure::Common::Real diff;
    for (size_t i = 0; i < modalTest.size (); ++i)
    {
        diff = modalTest[i] - modalTarget[i];
        numerator_norm += diff * diff;
        denominator_norm += modalTarget[i] * modalTarget[i];
    }
    numerator_norm        = std::sqrt (numerator_norm);
    denominator_norm      = std::sqrt (denominator_norm);
    SG::DataStructure::Common::Real relative_error = numerator_norm / denominator_norm;
    ASSERT_LE (relative_error, para.m_error);
};
std::vector<SG::DataStructure::Common::Real> modalTargetModal = {
    0.000000E+00,  1.889019E-08,  1.351961E-07,  4.127238E-07,  9.012747E-07,  1.651757E-06,  2.720010E-06,  4.166733E-06,  6.056319E-06,
    8.454796E-06,  1.142804E-05,  1.504159E-05,  1.936168E-05,  2.445620E-05,  3.039447E-05,  3.724592E-05,  4.507871E-05,  5.395888E-05,
    6.394973E-05,  7.511135E-05,  8.750369E-05,  1.011871E-04,  1.162210E-04,  1.326636E-04,  1.505705E-04,  1.699951E-04,  1.909881E-04,
    2.135979E-04,  2.378704E-04,  2.638490E-04,  2.915745E-04,  3.210855E-04,  3.524189E-04,  3.856102E-04,  4.206942E-04,  4.577049E-04,
    4.966733E-04,  5.376301E-04,  5.806081E-04,  6.256400E-04,  6.727566E-04,  7.219869E-04,  7.733571E-04,  8.268922E-04,  8.826165E-04,
    9.405540E-04,  1.000729E-03,  1.063165E-03,  1.127886E-03,  1.194915E-03,  1.264276E-03,  1.335994E-03,  1.410091E-03,  1.486588E-03,
    1.565501E-03,  1.646850E-03,  1.730653E-03,  1.816926E-03,  1.905681E-03,  1.996925E-03,  2.090662E-03,  2.186893E-03,  2.285617E-03,
    2.386831E-03,  2.490532E-03,  2.596713E-03,  2.705369E-03,  2.816492E-03,  2.930076E-03,  3.046113E-03,  3.164595E-03,  3.285506E-03,
    3.408832E-03,  3.534565E-03,  3.662691E-03,  3.793196E-03,  3.926061E-03,  4.061263E-03,  4.198780E-03,  4.338586E-03,  4.480655E-03,
    4.624960E-03,  4.771476E-03,  4.920172E-03,  5.071021E-03,  5.223997E-03,  5.379072E-03,  5.536219E-03,  5.695401E-03,  5.856583E-03,
    6.019733E-03,  6.184818E-03,  6.351803E-03,  6.520649E-03,  6.691315E-03,  6.863757E-03,  7.037929E-03,  7.213786E-03,  7.391280E-03,
    7.570364E-03,  7.750988E-03,  7.933102E-03,  8.116660E-03,  8.301613E-03,  8.487914E-03,  8.675510E-03,  8.864342E-03,  9.054360E-03,
    9.245514E-03,  9.437754E-03,  9.631032E-03,  9.825299E-03,  1.002051E-02,  1.021661E-02,  1.041355E-02,  1.061130E-02,  1.080980E-02,
    1.100902E-02,  1.120890E-02,  1.140941E-02,  1.161051E-02,  1.181214E-02,  1.201428E-02,  1.221686E-02,  1.241984E-02,  1.262316E-02,
    1.282679E-02,  1.303068E-02,  1.323478E-02,  1.343906E-02,  1.364348E-02,  1.384799E-02,  1.405257E-02,  1.425718E-02,  1.446177E-02,
    1.466632E-02,  1.487079E-02,  1.507515E-02,  1.527936E-02,  1.548339E-02,  1.568719E-02,  1.589071E-02,  1.609390E-02,  1.629673E-02,
    1.649916E-02,  1.670116E-02,  1.690269E-02,  1.710373E-02,  1.730425E-02,  1.750423E-02,  1.770365E-02,  1.790249E-02,  1.810073E-02,
    1.829836E-02,  1.849535E-02,  1.869169E-02,  1.888735E-02,  1.908231E-02,  1.927653E-02,  1.946998E-02,  1.966262E-02,  1.985442E-02,
    2.004538E-02,  2.023546E-02,  2.042465E-02,  2.061295E-02,  2.080033E-02,  2.098681E-02,  2.117236E-02,  2.135699E-02,  2.154070E-02,
    2.172347E-02,  2.190531E-02,  2.208621E-02,  2.226616E-02,  2.244513E-02,  2.262311E-02,  2.280007E-02,  2.297600E-02,  2.315089E-02,
    2.332475E-02,  2.349757E-02,  2.366936E-02,  2.384013E-02,  2.400989E-02,  2.417866E-02,  2.434645E-02,  2.451328E-02,  2.467917E-02,
    2.484413E-02,  2.500819E-02,  2.517134E-02,  2.533358E-02,  2.549491E-02,  2.565533E-02,  2.581483E-02,  2.597343E-02,  2.613113E-02,
    2.628795E-02,  2.644391E-02,  2.659902E-02,  2.675330E-02,  2.690679E-02,  2.705950E-02,  2.721146E-02,  2.736269E-02,  2.751322E-02,
    2.766307E-02,  2.781225E-02,  2.796078E-02,  2.810865E-02,  2.825586E-02,  2.840243E-02,  2.854835E-02,  2.869365E-02,  2.883832E-02,
    2.898240E-02,  2.912590E-02,  2.926884E-02,  2.941124E-02,  2.955313E-02,  2.969453E-02,  2.983546E-02,  2.997594E-02,  3.011599E-02,
    3.025563E-02,  3.039487E-02,  3.053370E-02,  3.067213E-02,  3.081018E-02,  3.094782E-02,  3.108509E-02,  3.122197E-02,  3.135847E-02,
    3.149462E-02,  3.163041E-02,  3.176586E-02,  3.190098E-02,  3.203579E-02,  3.217028E-02,  3.230449E-02,  3.243840E-02,  3.257204E-02,
    3.270540E-02,  3.283849E-02,  3.297131E-02,  3.310385E-02,  3.323611E-02,  3.336810E-02,  3.349980E-02,  3.363123E-02,  3.376238E-02,
    3.389324E-02,  3.402383E-02,  3.415414E-02,  3.428416E-02,  3.441391E-02,  3.454338E-02,  3.467258E-02,  3.480149E-02,  3.493012E-02,
    3.505848E-02,  3.518654E-02,  3.531432E-02,  3.544180E-02,  3.556897E-02,  3.569583E-02,  3.582236E-02,  3.594855E-02,  3.607439E-02,
    3.619985E-02,  3.632493E-02,  3.644961E-02,  3.657388E-02,  3.669771E-02,  3.682109E-02,  3.694402E-02,  3.706646E-02,  3.718841E-02,
    3.730986E-02,  3.743081E-02,  3.755123E-02,  3.767111E-02,  3.779042E-02,  3.790915E-02,  3.802727E-02,  3.814474E-02,  3.826155E-02,
    3.837765E-02,  3.849303E-02,  3.860764E-02,  3.872146E-02,  3.883447E-02,  3.894662E-02,  3.905789E-02,  3.916827E-02,  3.927773E-02,
    3.938627E-02,  3.949387E-02,  3.960050E-02,  3.970613E-02,  3.981074E-02,  3.991429E-02,  4.001674E-02,  4.011807E-02,  4.021822E-02,
    4.031717E-02,  4.041487E-02,  4.051128E-02,  4.060636E-02,  4.070009E-02,  4.079242E-02,  4.088333E-02,  4.097282E-02,  4.106086E-02,
    4.114744E-02,  4.123254E-02,  4.131613E-02,  4.139820E-02,  4.147870E-02,  4.155761E-02,  4.163489E-02,  4.171051E-02,  4.178442E-02,
    4.185659E-02,  4.192698E-02,  4.199556E-02,  4.206229E-02,  4.212714E-02,  4.219009E-02,  4.225112E-02,  4.231025E-02,  4.236745E-02,
    4.242270E-02,  4.247601E-02,  4.252733E-02,  4.257666E-02,  4.262396E-02,  4.266920E-02,  4.271236E-02,  4.275341E-02,  4.279231E-02,
    4.282902E-02,  4.286353E-02,  4.289578E-02,  4.292577E-02,  4.295346E-02,  4.297886E-02,  4.300196E-02,  4.302275E-02,  4.304123E-02,
    4.305739E-02,  4.307121E-02,  4.308269E-02,  4.309180E-02,  4.309853E-02,  4.310285E-02,  4.310474E-02,  4.310417E-02,  4.310112E-02,
    4.309557E-02,  4.308749E-02,  4.307687E-02,  4.306367E-02,  4.304791E-02,  4.302959E-02,  4.300870E-02,  4.298524E-02,  4.295922E-02,
    4.293063E-02,  4.289946E-02,  4.286570E-02,  4.282936E-02,  4.279042E-02,  4.274886E-02,  4.270468E-02,  4.265785E-02,  4.260838E-02,
    4.255623E-02,  4.250141E-02,  4.244390E-02,  4.238371E-02,  4.232084E-02,  4.225530E-02,  4.218710E-02,  4.211624E-02,  4.204273E-02,
    4.196658E-02,  4.188778E-02,  4.180634E-02,  4.172228E-02,  4.163557E-02,  4.154624E-02,  4.145427E-02,  4.135966E-02,  4.126242E-02,
    4.116254E-02,  4.106002E-02,  4.095487E-02,  4.084710E-02,  4.073672E-02,  4.062374E-02,  4.050818E-02,  4.039003E-02,  4.026932E-02,
    4.014605E-02,  4.002025E-02,  3.989191E-02,  3.976105E-02,  3.962767E-02,  3.949180E-02,  3.935342E-02,  3.921254E-02,  3.906918E-02,
    3.892333E-02,  3.877500E-02,  3.862421E-02,  3.847096E-02,  3.831527E-02,  3.815714E-02,  3.799659E-02,  3.783363E-02,  3.766827E-02,
    3.750052E-02,  3.733042E-02,  3.715795E-02,  3.698315E-02,  3.680602E-02,  3.662657E-02,  3.644482E-02,  3.626077E-02,  3.607443E-02,
    3.588581E-02,  3.569493E-02,  3.550180E-02,  3.530641E-02,  3.510879E-02,  3.490894E-02,  3.470688E-02,  3.450262E-02,  3.429618E-02,
    3.408758E-02,  3.387683E-02,  3.366396E-02,  3.344898E-02,  3.323191E-02,  3.301276E-02,  3.279155E-02,  3.256830E-02,  3.234301E-02,
    3.211570E-02,  3.188640E-02,  3.165510E-02,  3.142181E-02,  3.118657E-02,  3.094937E-02,  3.071024E-02,  3.046920E-02,  3.022627E-02,
    2.998147E-02,  2.973483E-02,  2.948637E-02,  2.923611E-02,  2.898408E-02,  2.873029E-02,  2.847477E-02,  2.821754E-02,  2.795861E-02,
    2.769801E-02,  2.743575E-02,  2.717185E-02,  2.690632E-02,  2.663920E-02,  2.637048E-02,  2.610021E-02,  2.582840E-02,  2.555508E-02,
    2.528028E-02,  2.500402E-02,  2.472633E-02,  2.444724E-02,  2.416678E-02,  2.388496E-02,  2.360182E-02,  2.331737E-02,  2.303166E-02,
    2.274469E-02,  2.245649E-02,  2.216708E-02,  2.187648E-02,  2.158473E-02,  2.129185E-02,  2.099786E-02,  2.070279E-02,  2.040668E-02,
    2.010955E-02,  1.981144E-02,  1.951238E-02,  1.921239E-02,  1.891152E-02,  1.860979E-02,  1.830722E-02,  1.800376E-02,  1.769937E-02,
    1.739404E-02,  1.708775E-02,  1.678047E-02,  1.647218E-02,  1.616284E-02,  1.585242E-02,  1.554088E-02,  1.522821E-02,  1.491435E-02,
    1.459930E-02,  1.428300E-02,  1.396544E-02,  1.364658E-02,  1.332640E-02,  1.300486E-02,  1.268196E-02,  1.235767E-02,  1.203198E-02,
    1.170485E-02,  1.137628E-02,  1.104625E-02,  1.071474E-02,  1.038174E-02,  1.004725E-02,  9.711245E-03,  9.373734E-03,  9.034712E-03,
    8.694182E-03,  8.352150E-03,  8.008623E-03,  7.663609E-03,  7.317121E-03,  6.969167E-03,  6.619763E-03,  6.268920E-03,  5.916653E-03,
    5.562974E-03,  5.207898E-03,  4.851439E-03,  4.493610E-03,  4.134427E-03,  3.773904E-03,  3.412055E-03,  3.048895E-03,  2.684440E-03,
    2.318704E-03,  1.951705E-03,  1.583461E-03,  1.213991E-03,  8.433149E-04,  4.714557E-04,  9.843683E-05,  -2.757165E-04, -6.509774E-04,
    -1.027318E-03, -1.404707E-03, -1.783116E-03, -2.162510E-03, -2.542856E-03, -2.924119E-03, -3.306264E-03, -3.689251E-03, -4.073043E-03,
    -4.457600E-03, -4.842882E-03, -5.228844E-03, -5.615445E-03, -6.002641E-03, -6.390386E-03, -6.778635E-03, -7.167341E-03, -7.556457E-03,
    -7.945936E-03, -8.335731E-03, -8.725791E-03, -9.116070E-03, -9.506519E-03, -9.897089E-03, -1.028773E-02, -1.067839E-02, -1.106903E-02,
    -1.145960E-02, -1.185003E-02, -1.224029E-02, -1.263033E-02, -1.302009E-02, -1.340951E-02, -1.379856E-02, -1.418717E-02, -1.457529E-02,
    -1.496287E-02, -1.534985E-02, -1.573618E-02, -1.612180E-02, -1.650666E-02, -1.689070E-02, -1.727386E-02
};
SG::Algebra::Real_t errorModal = 0.000137;
INSTANTIATE_TEST_CASE_P (ModalTransientAnalysis,
                         TransientModalTest,
                         testing::Values (TransientModalAnalysisTestData{ "ModalTransientModel.bdf", modalTargetModal, errorModal }));
